Jetpack DataStore 是一種數據存儲解決方案,允許您使用協議緩衝區存儲鍵值對或類型化物件。DataStore使用Kotlin協程和Flow以異步、一致的事務方式存儲數據。
如果您當前在使用"SharedPreferences"存儲數據,請考慮遷移到DataStore
。
注意!
如果需要支持大型或複雜的數據、部分更新、參照完整性,請考慮使用"Room",而不是DataStore。
功能 | SharedPreferences(SP) | Preferences DataStore | Proto DataStore |
---|---|---|---|
異步API | ✔️(僅在使用listener讀取值的修改時) | ✔️(通過Flow) | ✔️(通過Flow) |
同步API | ✔️(但在UI線程調用不安全) | ❌ | ❌ |
UI線程調用安全 | ❌ | ✔️(在內部將操作移至Dispatchers.IO ) |
✔️(在內部將操作移至Dispatchers.IO ) |
可以發出異常信號 | ❌ | ✔️ | ✔️ |
避免運行時異常 | ❌ | ✔️ | ✔️ |
具備事務處理 | ❌ | ✔️ | ✔️ |
處理數據遷移 | ❌ | ✔️(遷移至SP) | ✔️(遷移至SP) |
型別安全 | ❌ | ❌ | ✔️(使用Protocal Buffers) |
// Preferences DataStore (SharedPreferences like APIs)
dependencies {
implementation "androidx.datastore:datastore-preferences:1.0.0"
// 可選 - 支持RxJava2
implementation "androidx.datastore:datastore-preferences-rxjava2:1.0.0"
// 可選 - 支持RxJava3
implementation "androidx.datastore:datastore-preferences-rxjava3:1.0.0"
}
plugins {
...
id 'com.google.protobuf' version '0.8.12' apply false
}
plugins {
...
id "com.google.protobuf"
}
// Typed DataStore (Typed API surface, such as Proto)
dependencies {
implementation "androidx.datastore:datastore:1.0.0"
implementation "com.google.protobuf:protobuf-javalite:3.14.0"
// 可選 - 支持RxJava2
implementation "androidx.datastore:datastore-rxjava2:1.0.0"
// 可選 - 支持RxJava3
implementation "androidx.datastore:datastore-rxjava3:1.0.0"
}
protobuf {
protoc {
// 這裡設置的版本要和implementation "protobuf-javalite"的版本一致
artifact = "com.google.protobuf:protoc:3.14.0"
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option "lite"
}
}
}
}
}
步驟:
MyDataStore.java
// 定義DataStore的文件名稱
private static final String FILE_NAME = "MY_APP";
// 聲明MyDataStore存儲數據的KEY鍵
public final static Preferences.Key<String> NAME_KEY = PreferencesKeys.stringKey("name");
public final static Preferences.Key<Integer> AGE_KEY = PreferencesKeys.intKey("age");
private static RxDataStore<Preferences> dataStore;
MyDataStore.java
public MyDataStore(Context context) {
if (dataStore == null) {
dataStore = new RxPreferenceDataStoreBuilder(context, /*name=*/ FILE_NAME).build();
}
};
MyDataStore.java
/**
* 寫入數據
*/
public <T> void putValue(Preferences.Key<T> key, T value) {
dataStore.updateDataAsync(new Function<Preferences, Single<Preferences>>() {
@Override
public Single<Preferences> apply(Preferences preferences) throws Throwable {
MutablePreferences mutablePreferences = preferences.toMutablePreferences();
mutablePreferences.set(key, value);
Log.e("DataStore_Demo", "寫入數據__" + key + "->" + value);
return Single.just(mutablePreferences);
}
});
}
/**
* 獲取數據
*/
public <T> T getValue(Preferences.Key<T> key) {
Flowable<T> value = dataStore.data().map(new Function<Preferences, T>() {
@Override
public T apply(Preferences preferences) throws Throwable {
return preferences.get(key);
}
});
return value.blockingFirst();
}
MainActivity.java
MyDataStore dataStore = new MyDataStore(/*context=*/this);
// 寫入數據
dataStore.putValue(MyDataStore.NAME_KEY, "Chen");
dataStore.putValue(MyDataStore.AGE_KEY, 66);
// 讀取數據
String name = dataStore.getValue(MyDataStore.NAME_KEY);
Integer age = dataStore.getValue(MyDataStore.AGE_KEY);
Log.d("DataStore_Demo", "讀取數據__" + "name:" + name + ", age:" + age);
這篇明天在介紹, (補上連結 https://ithelp.ithome.com.tw/articles/10307040 )